package william.queue;

/**
 * @author ZhangShenao
 * @date 2024/1/22
 * @description <a href="https://leetcode.cn/problems/design-circular-queue/description/">...</a>
 */
public class Leetcode622_设计循环队列 {
    /**
     * 采用循环数组实现
     */
    class MyCircularQueue {
        /**
         * 底层采用数组保存元素
         */
        private int[] arr;

        /**
         * 记录当前队列中元素数量
         */
        private int size;

        /**
         * 队列的容量上限
         */
        private int capacity;

        /**
         * 记录队列头索引
         */
        private int front;

        /**
         * 记录队列尾索引
         */
        private int rear;

        /**
         * 构造器,设置队列长度为k
         */
        public MyCircularQueue(int k) {
            if (k <= 0) {
                throw new IllegalArgumentException("queue capacity must by positive!");
            }

            //初始化
            this.arr = new int[k];
            this.size = 0;
            this.capacity = k;
            this.front = this.rear = 0;
        }

        /**
         * 向循环队列插入一个元素,如果成功插入则返回真
         */
        public boolean enQueue(int value) {
            //校验队列是否已满
            if (isFull()) {
                return false;
            }

            //在队尾入队
            arr[rear] = value;

            //修改队尾索引
            rear = (rear + 1) % capacity;

            //修改长度
            ++size;

            return true;
        }

        /**
         * 从循环队列中删除一个元素,如果成功删除则返回真。
         */
        public boolean deQueue() {
            //校验队列是否为空
            if (isEmpty()) {
                return false;
            }

            //修改队头指针
            front = (front + 1) % capacity;

            //修改长度
            --size;

            return true;
        }

        /**
         * 从队首获取元素。如果队列为空,返回-1
         */
        public int Front() {
            //校验队列是否为空
            if (isEmpty()) {
                return -1;
            }

            //返回队头元素
            return arr[front];
        }

        /**
         * 获取队尾元素。如果队列为空,返回-1。
         */
        public int Rear() {
            //校验队列是否为空
            if (isEmpty()) {
                return -1;
            }

            //返回队尾元素
            int idx = (rear + capacity - 1) % capacity;
            return arr[idx];
        }

        public boolean isEmpty() {
            return (size == 0);
        }

        public boolean isFull() {
            return (size == capacity);
        }
    }
}
